"""结构化日志配置"""

import logging
import sys
import os
import json
import datetime
from typing import Dict, Any, Optional
from pythonjsonlogger import jsonlogger

class TraceIdFilter(logging.Filter):
    """用于在日志中添加trace_id的过滤器"""
    
    def __init__(self, trace_id: str):
        self.trace_id = trace_id
        super().__init__()
        
    def filter(self, record):
        # 添加trace_id到日志记录
        record.trace_id = self.trace_id
        return True

# 定义日志级别
LOG_LEVELS = {
    'DEBUG': logging.DEBUG,
    'INFO': logging.INFO,
    'WARNING': logging.WARNING,
    'WARN': logging.WARNING,
    'ERROR': logging.ERROR,
    'CRITICAL': logging.CRITICAL
}

class CustomJsonFormatter(jsonlogger.JsonFormatter):
    """自定义JSON日志格式化器"""
    
    def add_fields(self, log_record, record, message_dict):
        # 调用父类方法添加基本字段
        super().add_fields(log_record, record, message_dict)
        
        # 添加时间戳 - 使用datetime替代strftime以支持毫秒
        if not log_record.get('timestamp'):
            now = datetime.datetime.now()
            log_record['timestamp'] = now.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
        
        # 添加日志级别
        if log_record.get('level'):
            log_record['level'] = log_record['level'].upper()
        else:
            log_record['level'] = record.levelname
        
        # 添加进程和线程信息
        log_record['process_id'] = record.process
        log_record['thread_id'] = record.thread
        
        # 添加来源信息
        log_record['source'] = f"{record.module}:{record.funcName}:{record.lineno}"
        
        # 如果有异常信息，格式化异常
        if record.exc_info:
            log_record['exception'] = self.formatException(record.exc_info)

def setup_logging(log_level: str = 'INFO', log_format: str = 'json'):
    """设置全局日志配置
    
    Args:
        log_level: 日志级别
        log_format: 日志格式，支持'json'和'text'
    """
    # 获取根日志器
    root_logger = logging.getLogger()
    
    # 清除已有的处理器
    root_logger.handlers.clear()
    
    # 设置日志级别
    root_logger.setLevel(LOG_LEVELS.get(log_level.upper(), logging.INFO))
    
    # 创建控制台处理器
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.setLevel(LOG_LEVELS.get(log_level.upper(), logging.INFO))
    
    # 根据格式类型设置格式化器
    if log_format == 'json':
        formatter = CustomJsonFormatter(
            '%(timestamp)s %(level)s %(name)s %(message)s',
            json_encoder=json.JSONEncoder
        )
    else:
        formatter = logging.Formatter(
            '%(asctime)s [%(levelname)s] [%(name)s] %(message)s'
        )
    
    # 设置格式化器
    console_handler.setFormatter(formatter)
    
    # 添加处理器到根日志器
    root_logger.addHandler(console_handler)
    
    # 创建文件处理器（如果配置了日志文件）
    try:
        from backend.common.config import config_manager
        if hasattr(config_manager, 'logging') and hasattr(config_manager.logging, 'log_file') and config_manager.logging.log_file:
            log_file = config_manager.logging.log_file
            
            # 确保日志目录存在
            log_dir = os.path.dirname(log_file)
            if log_dir and not os.path.exists(log_dir):
                try:
                    os.makedirs(log_dir)
                    print(f"已创建日志目录: {log_dir}")
                except Exception as e:
                    print(f"创建日志目录失败: {str(e)}")
                    return
                
            try:
                file_handler = logging.FileHandler(log_file)
                file_handler.setLevel(LOG_LEVELS.get(log_level.upper(), logging.INFO))
                file_handler.setFormatter(formatter)
                root_logger.addHandler(file_handler)
                print(f"已配置文件日志处理器: {log_file}")
            except Exception as e:
                # 如果创建文件处理器失败，记录错误但继续执行
                temp_logger = logging.getLogger('logging.setup')
                temp_logger.error(f"Failed to create log file handler: {str(e)}")
    except Exception as e:
        print(f"配置文件日志处理器时发生错误: {str(e)}")

def get_logger(name: str, trace_id: Optional[str] = None) -> logging.Logger:
    """获取指定名称的日志器
    
    Args:
        name: 日志器名称
        trace_id: 可选的trace_id
        
    Returns:
        配置好的日志器
    """
    logger = logging.getLogger(name)
    
    # 如果提供了trace_id，添加过滤器
    if trace_id:
        # 移除已有的TraceIdFilter
        for filter in logger.filters[:]:
            if isinstance(filter, TraceIdFilter):
                logger.removeFilter(filter)
        
        # 添加新的TraceIdFilter
        logger.addFilter(TraceIdFilter(trace_id))
    
    return logger

def get_logger_with_trace_id(logger: logging.Logger, trace_id: str) -> logging.Logger:
    """获取带有trace_id的日志器
    
    Args:
        logger: 原始日志器
        trace_id: trace_id
        
    Returns:
        带有trace_id的日志器
    """
    # 创建一个新的日志器，继承原始日志器的配置
    new_logger = logging.getLogger(f"{logger.name}.trace.{trace_id[:8]}")
    new_logger.setLevel(logger.level)
    
    # 复制处理器
    for handler in logger.handlers:
        new_logger.addHandler(handler)
    
    # 添加trace_id过滤器
    new_logger.addFilter(TraceIdFilter(trace_id))
    
    return new_logger

def log_context(context: Dict[str, Any]) -> Dict[str, Any]:
    """创建带有上下文信息的日志记录
    
    Args:
        context: 上下文信息
        
    Returns:
        格式化的日志记录
    """
    # 确保上下文是可JSON序列化的
    serializable_context = {}
    for key, value in context.items():
        try:
            json.dumps({key: value})  # 测试是否可序列化
            serializable_context[key] = value
        except (TypeError, OverflowError):
            # 如果不可序列化，转换为字符串
            serializable_context[key] = str(value)
    
    return serializable_context

# 导出主要函数和类
__all__ = [
    'setup_logging',
    'get_logger',
    'get_logger_with_trace_id',
    'log_context',
    'CustomJsonFormatter',
    'TraceIdFilter'
]